home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / HEAP_UTL / HDEB20S / README.TXT < prev    next >
Text File  |  1995-04-17  |  45KB  |  978 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.                                      The
  20.  
  21.                               HEAP DEBUGGER V2.0
  22.  
  23.                                      for
  24.                              BORLAND PASCAL V7.0
  25.                            (DOS, DOS/DPMI, WINDOWS)
  26.  
  27.  
  28.                                 Copyright 1995
  29.                                       by
  30.  
  31.                                    AIT GmbH
  32.                          Alte Gasse 12 - 86152 Augsburg
  33.                                     Germany
  34.  
  35.                             Tel. +49 (821) 514868
  36.                             Fax: +49 (821) 514831
  37.  
  38.                   FIDO-Net: Karsten Strobel @ 2:2480/300.7
  39.                   Internet: kstrobel@gewi.muc.nacamar.de
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.                                         CONTENTS
  47.  
  48.  
  49.       INTRUDUCTION
  50.  
  51.       Why Heap Debugging ? ................................................  3
  52.       What the Heap Debugger CAN do........................................  3
  53.       What the Heap Debugger CANNOT do ....................................  3
  54.       The usage of Dynamic Memory .........................................  3
  55.       Versions and Targetplatforms ........................................  4
  56.       List of the Files ...................................................  5
  57.       Shareware Concept ...................................................  5
  58.       Licence Conditions ..................................................  5
  59.       Usertips and Warranty Limitation ....................................  6
  60.  
  61.       USING THE HEAP DEBUGGER
  62.  
  63.       Linking the Heap Debugger ...........................................  6
  64.       Compiler- and Linkeradjustments .....................................  6
  65.       When the Initialization fails .......................................  7
  66.       The Heap Debugger Report ............................................  7
  67.       Special Messages in the Heap Debugger Report ........................  9
  68.       Interpretation of the Report ......................................... 9
  69.       Hunting for Bugs .................................................... 10
  70.       Working with the External Debugger .................................. 11
  71.       Compilerswitches in USEHDEB ......................................... 11
  72.  
  73.  
  74.       HEAP DEBUGGING IN DETAIL
  75.  
  76.       Overlays ............................................................ 12
  77.       DLLs ................................................................ 12
  78.       Program instances (Windows) ......................................... 13
  79.       Interrupts .......................................................... 13
  80.       Stability and Performance ........................................... 13
  81.       Intervention possibilities for the Programmer ....................... 14
  82.  
  83.  
  84.       KNOWN LIMITATIONS AND PROBLEMS
  85.  
  86.       Mark/Release ........................................................ 15
  87.       MemAllocSeg ......................................................... 15
  88.       BGI ................................................................. 16
  89.       TMemoryStream ....................................................... 16
  90.       Heap Overrun ........................................................ 17
  91.       Program Halt ........................................................ 17
  92.       WINCRT .............................................................. 17
  93.  
  94.       Page 3
  95.  
  96.  
  97.       INTRODUCTION____________________________________________________________
  98.  
  99.       ___ Why Heap Debugging ? _______________________________________________
  100.  
  101.       The Heap Debugger controls (nearly) all by the program preformed heap
  102.       operations and writes among other things a list of all heap memory
  103.       areas that were not released. The programmer, who uses the Heap Debug-
  104.       ger while developing his program, will be notified about the remaining
  105.       Memoryblocks after every ending of his program.
  106.  
  107.       The Heap Debugger makes the finding of mistakes extremely easy, because
  108.       it gives (often) a note about the source code location (file name and
  109.       line number), where incorrect heap operations were preformed, or where
  110.       a not released memory block was allocated.
  111.  
  112.       Herefor the Heap Debugger uses the debug information for the external
  113.       Debugger, that (optionally) the is created by the compiler and that
  114.       extends the EXE-files.
  115.  
  116.  
  117.       ___ What the Heap Debugger CAN do ______________________________________
  118.  
  119.       The Heap Debugger controls all allocations of meap memory, that are
  120.       performed with the commands
  121.  
  122.          - GetMem
  123.          - New
  124.          - FreeMem
  125.          - Dispose
  126.  
  127.       Also calls of these routines from within the runtime-library and from
  128.       program-parts, that are not available in sourcecode (for example
  129.       foreign TPU's) are considered.
  130.  
  131.       All non correct deallocated heap memory blocks and other false heap
  132.       operations are listed in the Heap Debugger Report.
  133.  
  134.  
  135.       ___ What the Heap Debugger CANNOT do ___________________________________
  136.  
  137.       The following heap operations cannot be controlled by the Heap Debugger:
  138.  
  139.          - Mark and Release (are not allowed to be used !)
  140.  
  141.          - direct access to the global heap (DPMI+Windows),
  142.            so all "Global..."-calls
  143.  
  144.          - direct access to the local heap (Windows),
  145.            so all "Local..."-calls
  146.  
  147.  
  148.       ___ The Usage of Dynamic Memory _______________________________________
  149.  
  150.       In programs, that uses heap memory intensively, not seldom treacherous
  151.       programming errors are made: when dynamicly requested memory blocks
  152.       are not released correctly, the available heap memory stepwise
  153.       shrinks all together, so that sometime for a new request not enough
  154.       space remains and the program may stop or collapse.
  155.  
  156.       Page 4
  157.  
  158.  
  159.       It only comes to a complete consumption of the heap memory, when
  160.       allocations without deallocating, not only once, but again and again
  161.       are preformed. Such allocations could work a few hundret times until the
  162.       whole heap memory is used up. So such crashes will normally happen later
  163.       to the user, who of course does not know why.
  164.  
  165.       There are also allocations, that only once, so for instance in the
  166.       initialg process are done, because the program uses heap memory space
  167.       for quasi-static variables. The programmer could allocate such variables
  168.       (respectively structures or objects) into the data segment (as global
  169.       variables), but since the size of the data segment is limited to
  170.       a total of 64KB, he will sometimes misuse the Heap as a way out. When
  171.       such (only once allocated) quasi-static variables are not released, then
  172.       this is only a disfigurement, and has no other consequences. The Heap
  173.       Debugger criticizes of course also such offences.
  174.  
  175.       Particularly treacherous are deallocation errors, that means incorrect
  176.       released memory. A deallocation error is when with the releasing of
  177.       heap memory a false address or a false length is directed, so to the
  178.       undertaken deallocation no allocation was processed before. Since the
  179.       runtime-library mostly relies upon the information the programmer gives,
  180.       deallocation errors can have disastrous consequences.
  181.  
  182.       Especially the object oriented programming makes intensively use of heap
  183.       memory. For every new dynamic instance of an object type there will be a
  184.       heap allocated for the fields of the object, that when deleting then
  185.       object instance must be released. Herefor you use the commands NEW and
  186.       DISPOSE in the for OOP-use extended syntax. Also forgotten objects
  187.       consume heap memory.
  188.  
  189.  
  190.       ___ Versions and Targetplatforms _______________________________________
  191.  
  192.       The Heap Debugger was developed and tested with
  193.  
  194.                   Borland Pascal V7.0 and V7.01
  195.  
  196.                   with the target systems
  197.                   - Real Mode (for this HDEB7?.TPU)
  198.                   - Protected Mode (for this HDEB7?.TPP)
  199.                   - Windows (for this HDEB7?.TPW)
  200.  
  201.                   under
  202.                   - DOS 6.2x
  203.                   - Windows V3.1
  204.                   - Windows for Workgroups V3.11
  205.                   - Windows NT 3.5 Workstation
  206.                   - OS/2 V2.11.
  207.  
  208.       A Version for Delphi V1.0 for Windows is be prepared.
  209.  
  210.       Page 5
  211.  
  212.  
  213.       ___ List of the Files __________________________________________________
  214.  
  215.       USEHDEB.PAS .... Unit to link to your pascal program, for
  216.                        DOS, DOS/DPMI and WINDOWS
  217.       HDEB7S.TPU ..... The core of the Heap Debugger,
  218.                        shareware version, for DOS/Real Mode
  219.       HDEB7S.TPP ..... The core of the Heap Debugger,
  220.                        shareware version, for DOS/Protected Mode
  221.       HDEB7S.TPW ..... The core of the Heap Debugger,
  222.                        shareware version, for Windows
  223.       HDEB7F.TPU ..... The core of the Heap Debugger,
  224.                        registered version, for DOS/Real Mode
  225.       HDEB7F.TPP ..... The core of the Heap Debugger,
  226.                        registered version, for DOS/Protected Mode
  227.       HDEB7F.TPW ..... The core of the Heap Debugger,
  228.                        registered version, for Windows
  229.       VIEWME.EXE ..... The Heap Debugger in pictures (sliteshow, req. VGA)
  230.       README.TXT ..... This text (english)
  231.       LIESMICH.TXT ... This text (german, in mare correct grammer!)
  232.       DIZFILES.ZIP ... Short description-files, for Sysops
  233.       SHARWARE.ZIP ... This file only conmes with registered versions and
  234.                        contains the sharewareversion
  235.       BESTELL.TXT .... Orderform (german)
  236.       ORDER.TXT ...... Orderform (english)
  237.  
  238.  
  239.       ___ Shareware Concept __________________________________________________
  240.  
  241.       The Heap Debugger is Shareware, not Public Domain or Freeware!
  242.  
  243.       The through the shareware distributers delivered version of the Heap
  244.       Debugger with the files HDEB7S.* ("S"=Shareware) and the accompanied
  245.       files and the file USEHDEB.PAS are allowed to be used for test purposes
  246.       and are allowed to be distributed freely.
  247.  
  248.       The shareware version is towards the registered version in its capacity
  249.       limited: The shareware version of the Heap Debugger controls only the
  250.       first 50 allocations of memory blocks. All following allocations will be
  251.       ignored. When exceeding the shareware limit there will come an
  252.       appropriate message in the report (at the end of the program).
  253.  
  254.       Registered versions of the Heap Debuggers contain the files HDEB7F.*
  255.       ("F"=Full). These files are not allowed to be distributed to third, or
  256.       to be made available for them.
  257.  
  258.  
  259.       ___ Licence Conditions _________________________________________________
  260.  
  261.       If you want to use the Heap Debugger in the unlimited version, you have
  262.       to register. With the delivery of the software you will receive a
  263.       licence for the usage on a single workstation.
  264.  
  265.       If you want to use the Heap Debugger on several workstations then you
  266.       have to register for every Workstation. Herefor we offer cheaper prices.
  267.  
  268.       A registration form is in the file ORDER.TXT prepared.
  269.  
  270.       Distribution of the registered version of the Heap Debugger is absolutely
  271.       prohibited. Especially the files HDEB7F.* must not be delivered to
  272.       thirds.
  273.  
  274.       Page 6
  275.  
  276.  
  277.       ___ Usertips and Warranty Limitations __________________________________
  278.  
  279.       Although we tested the Heap Debugger in detail before publishing, we
  280.       cannot give a guarantee for error-free function of this software.
  281.  
  282.       We suggest the usage of the Heap Debugger only during the developing
  283.       phase.
  284.  
  285.       The Heap Debugger shall help you in your software development to avoid
  286.       errors with the memory managment or delete them. We point to the
  287.       additional dangers of the stability of a software, that involves the
  288.       Heap Debugger. More information is given in the section "Stability and
  289.       Performance".
  290.  
  291.       For registered versions of the Heap Debugger we warrant the physical
  292.       media to be readable. We specifically disclaim all other warranties!
  293.  
  294.  
  295.       Using the Heap Debugger ________________________________________________
  296.  
  297.       ___ Linking the Heap Debugger __________________________________________
  298.  
  299.       To link the Heap Debugger into your program, you only have to insert
  300.       the unit UseHDeb in the uses-clause of your main program. For Example:
  301.  
  302.  
  303.             PROGRAM MyProg;
  304.  
  305.                UseHDeb,
  306.                 \  /
  307.                  \/
  308.             USES   Drivers, Objects, Views, Menus, ...
  309.  
  310.       It is a good idea, to list the Unit UseHDeb as the first Unit in the
  311.       uses-clause. The initialization of the Heap Debugger is done by the
  312.       initialization-section of this Unit. After the initialization the Heap
  313.       Debugger can "watch" heap operations. That is why the initialization
  314.       of UseHDeb should be done before other Units, that possibly already
  315.       preform heap operations.
  316.  
  317.  
  318.       ___ Compiler- and Linkeradjustments __________________________________
  319.  
  320.       "D+":
  321.  
  322.       The Heap Debugger will only be initialized when the Unit UseHDeb is
  323.       compiled with the option "D+" (debug-informations on). This is caused
  324.       by, that almost the whole Unit UseHDeb is excepted from the compilation
  325.       with the clause {$IFOPT D+}...{$ENDIF} otherwise. So this switch can be
  326.       used to turn the Heap Debugger on and off, alltho theoretic the Heap
  327.       Debugger could work without the D+ being turned on.
  328.  
  329.       All other Units, that are integrated in your program and also the main
  330.       program need to be compiled with the option D+ turned on, if you want
  331.       the to get source code references within the report.
  332.  
  333.       Page 7
  334.  
  335.  
  336.       "Link-Buffer: Disk" and "Standalone Debugging":
  337.  
  338.       Beside the compiler option D+ the adjustments "Link-Buffer: Disk" and
  339.       "Standalone Debugger" are also required. Under Windows the last option
  340.       is called "Debug-Info in EXE".
  341.  
  342.       "Unit-Directories: \BP\RTL\WIN" (DOS/DPMI and Windows):
  343.  
  344.       The Unit UseHDeb needs in the protected mode (DOS+Windows) the Unit
  345.       WINPROCS. This is found normally in the directory "\BP\RTL\WIN". Since
  346.       under DOS this index is normally not adjusted as a Unit-Directory (see
  347.       Options-->Directories), you must add this directory to the list of
  348.       unit-directories yourself.
  349.  
  350.  
  351.       ___ When the Initialization fails ______________________________________
  352.  
  353.       The initialization of the Heap Debugger is done through the initiali-
  354.       zation section of the unit UseHDeb. When it fails the UseHDeb reports
  355.       "Unable to initialize the Heap Debugger !" and stops the program with
  356.       the command HALT.
  357.  
  358.       The failing of the Initialization can have following reasons:
  359.  
  360.         - You are using a modified runtime-library, that in a for
  361.           the Heap Debugger important point does not match with the
  362.           original from Borland.
  363.         - You are using an operating system or a special tool (e.g.
  364.           memory management tool) that wasn't verified to supported.
  365.         - You are using an unsupported compiler version.
  366.         - There were no free interrupt vectors found. The Heap Debugger
  367.           needs three free interrupts. In this case probably our
  368.           test method for finding free interrupts did fail. It is
  369.           extremely rare that all interrupts are really used.
  370.         - The Heap Debugger is already initialized. This should not
  371.           happen when you use the Unit UseHDeb.
  372.  
  373.       When in your system the initialization fails, then please try to run
  374.       your program within a tested configuration (for instance: MSDOS 6.2 ,
  375.       Windows 3.1) without loading any special memory managers or multi-
  376.       taskers. Observe if the Heap Debugger can now be initialized in this
  377.       configuration.
  378.  
  379.       Please inform us about configuration in, with that the Heap Debugger
  380.       could not be used. (if possible per email)
  381.  
  382.  
  383.       ___ The Heap Debugger Report ___________________________________________
  384.  
  385.       The Heap Debugger gives a report when ending a program. This happens in
  386.       the exit-procedure of the unit UseHDeb.
  387.  
  388.       The Heap Debugger Report has normally the following structure
  389.       (for example:)
  390.  
  391.       Page 8
  392.  
  393.  
  394.         HEAP DEBUGGER DIAGNOSIS:
  395.         2 pointer were registered (*1)
  396.         1 debug-entries available (*2)
  397.         list (Y/N) ? y
  398.  
  399.         (*3)  (*4)      (*5)  (*6)           (*7)       |------(*8)------|
  400.         No    Pointer   Size  Flags            Caller          File   Line
  401.          2  1A41:0000    256          0000[122D]:0044   HEAPBUG.PAS     16
  402.  
  403.  
  404.       (*1): Here is printed, how many heap allocations the Heap Debugger did
  405.             observe in total. This number means no statement about possible
  406.             mistakes.
  407.       (*2): Here is printed, how many diagnosis lines the Heap Debugger has
  408.             available to dump. In the best case this number should always
  409.             be "0". Not all but most of the diagnosis lines point towards a
  410.             programming error.
  411.       (*3): Here is a sequential counter of all in the program done
  412.             allocations. With deallocations (Flag "F") this place is empty.
  413.       (*4): Here is the addresses of the allocated respectively deallocated
  414.             heap memory block printed. This address can vary from program-run
  415.             to program-run.
  416.       (*5): Here is the size of the allocated respectively deallocated block
  417.             printed.
  418.       (*6): The here listed Flags have following meanings
  419.             (combinations are possible):
  420.  
  421.             none : Its about an allocation, to that no fitting deallocation
  422.                    was performed.
  423.             "O"  : Its about an instance-data of an object type. This is the
  424.                    data area, that is created by the constructor of a object
  425.                    with every new instance. As caller is the line with the
  426.                    word "BEGIN" in the costructor given (the line with the
  427.                    word "END" in the destructor at deallocations).
  428.             "F"  : This diagnosis line deals with a deallocation (F=free).
  429.                    What went wrong with this deallocation is explained in one
  430.                    of the following flags.
  431.             "S"  : A heap memory block was not in the same blocklength
  432.                    (S=size) deallocated, with which it was allocated. In this
  433.                    case, the flag will appear both in the diagnosis lines of
  434.                    the allocation and of the deallocation.
  435.             "M"  : To a deallocation there was not a fitting allocation found
  436.                    (M=mismatch). This means, it was tried, to deallocate a
  437.                    heap memory block, who's address was not registered by a
  438.                    previous allocation. This flag appears only together with
  439.                    the flag "F".
  440.  
  441.       (*7): At this address the heap operation, that this diagnosis line is
  442.             about, was called. The segment address is the virtual segment
  443.             address and in brackets "[]" the actual segment address. The
  444.             virtual segment address is generated by the linker and is the
  445.             address relative to the address 0000. The actual segment address
  446.             will be given when loading a program and depends on the location,
  447.             at which the program is loaded into memory. The virtual address
  448.             can be found in the map-file. The actual address can vary from
  449.             program-run to program-run.
  450.  
  451.       Page 9
  452.  
  453.  
  454.       (*8): Here the sourcecode location (file name and line number) ist
  455.             shown according to the caller address. It is required that the
  456.             debug information exist in the EXE-file. If there are no debug
  457.             informations present "No Info" will be printed here. If there
  458.             are debug informations present but the sourcecode-line of the
  459.             caller address couldn't be found nonetheless, a "?" will be
  460.             printed here.
  461.  
  462.  
  463.       ___ Special Messages in the Heap Debugger Report _______________________
  464.  
  465.       The following messages can appear under special circumstances:
  466.  
  467.       "Program stopped by HALT(nnn)"
  468.  
  469.       This message says, that the program was stopped with the command
  470.       HALT(nnn). The Exitcode is given with nnn.
  471.  
  472.       "runtime-error nnn at ssss:oooo, file: ________ line: ______"
  473.  
  474.       When the program is stopped through a runtime error, this message will
  475.       be present. As additional, useful information the file name and line
  476.       number of the error are printed, if this information is available.
  477.  
  478.       "internal error 203 occured in Heap Debugger"
  479.  
  480.       This message means, that the Heap Debugger did not have enough heap
  481.       memory to record all heap operations.
  482.  
  483.       "Shareware-limit exceeded!
  484.        Only 50 pointers were registered!"
  485.  
  486.       This message will only be printed in the shareware version and tells us
  487.       that the shareware limit of 50 controlled allocations was exceeded
  488.       during the runtime.
  489.  
  490.  
  491.       ___ Interpretation of the Report _______________________________________
  492.  
  493.       Of course you should attempt to receive the message "0 debug-entries
  494.       available", at the end of a program-run. If the Heap Debugger is
  495.       continually in action during the development of a application, then an
  496.       possibly reported bugs can easly be found, because the error most often
  497.       was made during the last changes to the program.
  498.  
  499.       If the matter isn't so easy, then you first need to understand the
  500.       diagnosis of the Heap Debugger, to solve the problem.
  501.  
  502.       For this purpose you need to ask yourself following questions:
  503.  
  504.       - Is the number of the diagnosis entries always the same, or does this
  505.         number vary?
  506.  
  507.         As far as the number does not vary, then it must have to do with an
  508.         error that happens only once a program-run. There are cases, in that
  509.         the name error is to strong. Some programs allocate some quasi-static
  510.         variables on the Heap, and don't release them at the end. This behavior
  511.         is not very nice and should be tried to be avoided; on the other hand
  512.         this has no bad consequences.
  513.  
  514.       Page 10
  515.  
  516.  
  517.       - Can the increase of the number of diagnosis lines have to do with
  518.         certain functions of my program?
  519.  
  520.         If the number grows, then you should try to find the obviously
  521.         repeated error. Most often this is very easy, when the Heap Debugger
  522.         gives for several entries the same caller address. It then appears to
  523.         be a error, that always occurs when a certain program function is
  524.         executed. You should always get rid of these errors, because they can
  525.         cause "loss of memory".
  526.  
  527.       - Are there any Flags in a diagnosis lines?
  528.  
  529.         If not, then this diagnosis denunciats a "classic" error, particulary
  530.         a not released "normal" heap memory block, that was allocated with
  531.         GetMem or New. The sourcecode reference refers to the location, were
  532.         this demand happened.
  533.  
  534.       - Is the Flag "O" present ?
  535.  
  536.         If yes, the Heap Debugger shows an error in relation to an object.
  537.         If there is just an "O" entered, then this has to with a not released
  538.         dynamic instance of an object, which was set up with the command new
  539.         in the OOP-variation. The sourcecode reference does NOT point to this
  540.         New-command, but to the line BEGIN in the concerned constructor. If
  541.         you found out this, you need to think about where the instances of
  542.         this object type is allocated and to and check for the correct
  543.         releasement.
  544.  
  545.       - Is th Flag "F" present ?
  546.  
  547.         This flag appears never alone. It means (mostly), that a deallocation
  548.         error has occurred. Beside the "F" there will always be a "S" or a
  549.         "M", which means, that either a deallocation with a false block length
  550.         was called, or that the deallocated memory block has an address,
  551.         where no allocation was done.
  552.  
  553.         This diagnosis is either real bad or harmless. The harmless case
  554.         is described in the section "MemAllocSeg". If this description doesn't
  555.         prove, then there is probably a REAL error, that has to be found,
  556.         because it could cause the whole program (also the Heap Debugger) to
  557.         crash. This can happen, if the consistency of the heap management
  558.         becomes damaged.
  559.  
  560.  
  561.       ___ Hunting for Bugs ___________________________________________________
  562.  
  563.       If the Heap Debugger gives with his diagnosis sourcecode references,
  564.       then is the finding of bugs relatively easy.
  565.  
  566.       If instead of a sourcecode reference a "?" is printed, then the under
  567.       "Caller" listed address is in an module, that has not debug informations
  568.       because is wasn't compiled with the option "D+". Often you can find the
  569.       caller in the runtime-library.
  570.  
  571.       You should not let yourself come to the conclusion, that you are not
  572.       responsible for the error and that the runtime-library has a Bug. If you
  573.       for instance do an allocation with "NewStr" (function of the runtime
  574.  
  575.       Page 11
  576.  
  577.  
  578.       library) and the requested heap memory block then is not deallocated
  579.       afterwards with DisposeStr, then the error is in your program. But the
  580.       caller is a line in the function NewStr in the runtime library.
  581.  
  582.       A lot of these problems can be solved, if you recompile the whole run-
  583.       time-library with the debug-option. This is only possible with BP7.0
  584.       (not with TP7.0). Informations for this you find in Borland's
  585.       \BP\RTL\README.
  586.  
  587.  
  588.       ___ Working with the External Debugger _________________________________
  589.  
  590.       In hard cases you should try to find an error with the help of the
  591.       external debugger. That makes sense when the Heap Debugger did not
  592.       give sourcecode references.
  593.  
  594.       In the external Debugger you should set a breakpoint at the callers
  595.       address.
  596.  
  597.       Please notice the difference between the virtual and the actual
  598.       segment address, that the Heap Debugger prints.
  599.  
  600.       Attention: The actual segment address of the caller can vary from
  601.       program-run to program-run. After loading the Debugger it will mostly
  602.       move. Let your program run once or a few times with the loaded debugger
  603.       before you set a breakpoint. Use the last given actual segment address.
  604.       You can set a breakpoint at any adress function "Breakpoints-At...".
  605.       Just enter the caller address and start the segment address AND the
  606.       offsetaddress with a "$" for hexadecimal notation.
  607.  
  608.       When you reach a breakpoint, continue the execution stepwise until you
  609.       reach an area that you know.
  610.  
  611.  
  612.       ___ Compilerswitches in USEHDEB ________________________________________
  613.  
  614.       In the Unit UseHDeb there are already a few compiler switches established,
  615.       that eases the adjustment. We hope, that the most adjustment problems can
  616.       be solved, so that you don't need to change the source code.
  617.  
  618.       The Switch "USE_SHAREWARE":
  619.  
  620.       When this switch is defined, the Heap Debugger uses the unit
  621.       "HDEB7S.TP?". When it is undefined, then the Units "HDEB7F.TP?" is
  622.       integrated. This stands for the registered version of the Heap Debugger
  623.       and can of course only be used, if the software was registered. This
  624.       switch is correctly adjusted in the delivered shareware or the
  625.       registered version and does normally not need to be changed.
  626.  
  627.       The Switch "GERMAN_LANG":
  628.  
  629.       When this switch is defined, the Heap Debugger Report will be given in
  630.       german language instead of english.
  631.  
  632.       Page 12
  633.  
  634.  
  635.       The Switch "GETDEBUGINFO":
  636.  
  637.       When this switch is defined, then the Heap Debugger will try to access
  638.       to the debug informations in the EXE-file to find out the file name and
  639.       line number for every diagnosis line. This switch should normally stay
  640.       active.
  641.  
  642.       The Switch "REPORT_TO_FILE":
  643.  
  644.       When this switch is defined, then the report output will be transferred
  645.       into a file. The name of this file in defined in the constant
  646.       "DumpFileName" and that is preadjusted to "HEAPDEB.DMP" but can be
  647.       changed. The file will be enlarged with every report output. Please
  648.       note: When the Heap Debugger because of any reason cannot be initialized
  649.       and the switch "REPORT_TO_FILE" is active, then the program will be
  650.       stopped with the command "HALT" without any warning (also in the file).
  651.  
  652.       The Switch "SWITCH_TO_LASTMODE":
  653.  
  654.       When this switch is defined, the command "TextMode(LastMode)" will be
  655.       executed before the report output starts. The command switches back
  656.       into the videomode, that was active at the start of the program. This
  657.       can be very helpful when the main program switches to a graphics mode
  658.       that isn't BIOS-supported or when textcolors are modified in a way,
  659.       that the report in not readable. This switch does nothing under Windows.
  660.  
  661.  
  662.       Example for turning switches off and on:
  663.            active:   "{$DEFINE GERMAN_LANG}"
  664.            inactive: "{not $DEFINE GERMAN_LANG}"
  665.  
  666.  
  667.       HEAP DEBUGGING IN DETAIL _______________________________________________
  668.  
  669.       ___ Overlays ___________________________________________________________
  670.  
  671.       You can use the Heap Debugger also with programs, that uses overlay-
  672.       technics. The Units USEHDEB and HDEB7? cannot be loaded as overlays.
  673.  
  674.  
  675.       ___ DLLs _______________________________________________________________
  676.  
  677.       A DLL can be treated just like a normal self-running program. If a
  678.       program, that is using the Heap Debugger, loads a DLL at runtime, then
  679.       the Heap Debugger is not active for this DLL. On the other hand a DLL
  680.       can use the Heap Debugger, without the heap operations in the main
  681.       program being controlled. If the Heap Debugger is used for the DLL and
  682.       the main program, then there will be two reports printed.
  683.  
  684.       To link the Heap Debugger to a DLL just insert the unit UseHDeb in the
  685.       uses-clause of the librarys main file (with the title "Library").
  686.  
  687.       The exit-procedure of the unit UseHDeb (with the Reportoutput) will be
  688.       done when the DLL ends. When is this? The DLL normally ends, when also
  689.       the main program, that loaded the DLL, ends. But there are exceptions:
  690.       If the main program is run with the external debugger, then the DLL will
  691.       not end when the program is ended, but when the debugger is ended, what
  692.  
  693.       Page 13
  694.  
  695.  
  696.       very often leads to a system crash. We suggest to use the command
  697.       "FreeLibrary" to unload a DLL that uses the Heap Debugger. The report
  698.       for the DLL will than be printed immediately. What was just described
  699.       counts for DLLs under DOS and WINDOWS the same.
  700.  
  701.       Under Windows there is also another problem: The report output, that is
  702.       done by the unit UseHDeb under Windows is printed into a WinCrt-window.
  703.       That does not work with a DLL: The consequence of the try, to write into
  704.       a WinCrt-window from within a DLL, is a runtime error or a complete
  705.       missing of the output. Under DOS this problem will not occur.
  706.  
  707.       When using the Heap Debugger under Windows for a DLL, it is absolutely
  708.       necessary to dump the report into a file. Herefor the switch
  709.       "REPORT-TO-FILE" was prepared (see "Compilerswitches in USEHDEB").
  710.  
  711.  
  712.       ___ Program Instances (Windows) ________________________________________
  713.  
  714.       When under windows a program, that links the Heap Debugger is started
  715.       in several instances, the Heap Debugger will be installed only for the
  716.       first instance. The following instances automatically use the already
  717.       installed Heap Debugger. The output of the report will not be done until
  718.       the ending of the last active instance of that program. The report then
  719.       contains all wrong heap operations, that were done in all instances of
  720.       that program.
  721.  
  722.  
  723.       ___ Interrupts ________________________________________________________
  724.  
  725.       The Heap Debugger needs three free software interrupts. This means that
  726.       when the Heap Debugger is installed it changes three free interrupt
  727.       vectors and releases them at the end of the program. The Heap Debugger
  728.       finds the free vectors itself within the range 78h to FFh. From this
  729.       range you can exclude single vectors if you need some special vectors
  730.       for own purposes. To do so you must change the parameter of the command
  731.       "HeapDebInit([])". Change the empty set to set of vectors that you want
  732.       be be left unchanged, e.g. "HeapDebInit([$F0..$FF]).
  733.  
  734.  
  735.       ___ Stability and Performance __________________________________________
  736.  
  737.       As already explained the Heap Debugger should not be used as a part of a
  738.       finished application. The Heap Debugger should only be used during the
  739.       developing phase as a debugging tool.
  740.  
  741.       The permanent use of the Heap Debugger during the software development
  742.       can help stabilize the developed software a lot and shorten the
  743.       developmenting time.
  744.  
  745.       On the other hand the Heap Debugger can be a potential cause for
  746.       program crashes, even if this has not been discovered yet. Following
  747.       facts should be watched:
  748.  
  749.       - The Heap Debugger not only controls the correct usage of the heap
  750.         memory. It also requires meap memory itself for this task. If a
  751.         program occasionally has to allocate a large number of heap memory
  752.         blocks, so the amount of needed extra memory for the Heap Debugger
  753.         can be high. You should count with an extra 24 bytes for each
  754.         allocated (and not yet deallocated) memory block.
  755.  
  756.       Page 14
  757.  
  758.  
  759.       - The execution of the Heap Debugger requires extra space on the stack,
  760.         as well as the execution of the memory operations and also the
  761.         output of the report in the exit-procedure of the unit UseHDeb. Please
  762.         notice that no stack-checks are done so that a lack of stack-space
  763.         will cause a program crash.
  764.       - When fatal errors in the application program are made in using the
  765.         meap that can bring the program to a collapse. There might be
  766.         constallations, in that the program doesn't crash when the Heap
  767.         Debugger isn't linked. Nevertheless the causing error is dangerous.
  768.         Such crashes can for instance happen, when the application tries to
  769.         release a not allocated memory block.
  770.       - The Heap Debugger needs for its work additional CPU-time. The more
  771.         memory blocks are allocated, the more CPU-time the Heap Debugger
  772.         requires, especially for releasing memory.
  773.       - The Heap Debugger requires, as in the previous section mentioned, for
  774.         its work three free software interrupts. The tree vectors are set to
  775.         the addresses of three functions within the Heap Debugger and restored
  776.         at the end of the program. When a program suddenly ends because of a
  777.         fatal error and the exit procedure of the Unit UseHDeb insn't
  778.         executed, then the interrupt vectors are not set to their old values.
  779.         If such crashes happen very often, the Heap Debugger might not be able
  780.         to find any free Interrupts and wont start.
  781.  
  782.  
  783.       ___Intervention possibilities for the Programmer _______________________
  784.  
  785.       If you perhaps like to change the appearance of the Heap Debugger Report
  786.       you can modify the sourcecode of the unit UseHDeb. Changes are only
  787.       allowed for your own, non-commercial use.
  788.  
  789.       Beside the unit UseHDeb offers the following constants, which can be
  790.       changed during at runtime:
  791.  
  792.       1)   SuspendHeapdeb : Boolean = false;
  793.  
  794.       If this constant is set to TRUE at runtime, then there will be no heap
  795.       operations recorded by the Heap Debugger. After the reconversion of the
  796.       value to FALSE the Heap Debugger will work normal. This can be
  797.       useful to prevent quasi-static variables being listed in the report.
  798.  
  799.       2)   RecordZeroSize : Boolean = false;
  800.  
  801.       As long as this constant is FALSE, allocations and deallocations with
  802.       the a length of zero be ignored by the Heap Debugger. Because such
  803.       operations are just disfigurements and (as far as we know) cant make
  804.       damage, this constant is preadjusted to FALSE.
  805.  
  806.       3)   RTEOnWrongSizedFree : Byte = 0;
  807.  
  808.       If in this constant is not zero, every deallocation, that doesn't have
  809.       the same length as the fitting allocation (Flag "S"), will cause a
  810.       runtime error immediately. The number of the runtime error is
  811.       determined by this constant.
  812.  
  813.       4)   RTEOnUnknownFree : Byte = 0;
  814.  
  815.       If in this constant is not zero, every deallocation with not matching
  816.       allocation (Flag "M"), will cause a runtime error immediately. The
  817.       number of the runtime error is determined by this constant.
  818.  
  819.       Page 15
  820.  
  821.  
  822.       KNOWN LIMITATIONS AND PROBLEMS _________________________________________
  823.  
  824.       ___ Mark/Release _______________________________________________________
  825.  
  826.       The Heap Debugger doesn't work with these commands. The usage of Release
  827.       can cause the records of the Heap Debugger being destructed.
  828.  
  829.       However the commands Mark and Release are seldomly used, because
  830.       they bring other problem with them in general. Probably they are still
  831.       in the newest version of the compiler because of the compatibility. The
  832.       usage of Mark and Release we generally do not advise. Mark and Release
  833.       are only available under DOS.
  834.  
  835.  
  836.       ___ MemAllocSeg ________________________________________________________
  837.  
  838.       The function MemAllocSeg in the unit Memory (under Windows: OMemory)
  839.       is a big problem for the Heap Debugger: The job of this function
  840.       is, to allocate a heap memory area, who's start address is exactly at
  841.       the start of a memory segment (at the offset address 0000). To reach
  842.       this, the function MemAllocSeg must use some tricks. We have to make
  843.       differences between the target-platforms:
  844.  
  845.       Real Mode:
  846.  
  847.       To allocate a heap memory area with the offset address 0000, the
  848.       function MemAllocSeg reserves with GetMem initially a little larger
  849.       area, to afterwards immediately release with FreeMem a small part
  850.       (8 Bytes), that is either located at the start or at the end of the
  851.       just allocated area. Altho this is an offence against the rules, this
  852.       trick isn∩t really illegal. The Heap Debugger "watches" these operations
  853.       and will later list them in its report. This can for instance
  854.       look like this:
  855.  
  856.          program TEST;
  857.          uses UseHDeb, Memory;
  858.          var p: pointer;
  859.          begin
  860.            {...}
  861.            p := MemAllocSeg(100);
  862.            FreeMem(p, 100);
  863.          end.
  864.  
  865.       HEAP-DEBUGGER-DIAGNOSIS:
  866.       1 pointers were registered
  867.       3 debug-entries available
  868.       list (Y/N) ? y
  869.  
  870.       No    Pointer   Size  Flags            Caller          File   Line
  871.        1  1A4D:0000    112    S     020B[1438]:001F    MEMORY.PAS    327
  872.           1A53:0008      8   F M    020B[1438]:00D5    MEMORY.PAS    355
  873.           1A4D:0000    100   FS     0000[122D]:003A      TEST.PAS      7
  874.  
  875.       Or so:
  876.  
  877.       Page 16
  878.  
  879.  
  880.       HEAP-DEBUGGER-DIAGNOSIS:
  881.       1 pointers were registered
  882.       3 debug-entries available
  883.       list (Y/N) ? y
  884.  
  885.       No    Pointer   Size  Flags            Caller          File   Line
  886.        1  1531:0008    112    S     020C[0F1A]:001F    MEMORY.PAS    327
  887.           1531:0008      8   FS     020C[0F1A]:00D5    MEMORY.PAS    355
  888.           1532:0000    100   F M    0000[0D0E]:004A      TEST.PAS      7
  889.  
  890.       The programmer is more or less being forced, to accept such operations
  891.       altho they appear risky.
  892.  
  893.       Protected Mode (DOS/DPMI):
  894.  
  895.       Here the function MemAllocSeg has it easier then in Real Mode:
  896.       It just calls the function "MemAllocateBlock", which is made available
  897.       by RTM.EXE that calls a corresponding DPMI-function. Through this
  898.       a heap memory block is allocated, that starts at the offset address
  899.       0000. As already explained in section "Global and Local Heap",
  900.       the Heap Debugger notices nothing of this. The releasing of this
  901.       heap memory block is normally done with the function FreeMem, about
  902.       what the Heap Debugger takes notice. Our test program would show in
  903.       the protected mode the following report:
  904.  
  905.  
  906.       HEAP-DEBUGGER-DIAGNOSIS:
  907.       0 pointers were registered
  908.       1 debug-entries available
  909.       list (Y/N) ? y
  910.  
  911.         No    Pointer   Size  Flags            Caller          File   Line
  912.             059F:0000    100   F M    0001[0547]:003D      TEST.PAS      7
  913.  
  914.       Windows:
  915.  
  916.       Here we have the same situation as in the protected mode under DOS,
  917.       except that the MemAllocSeg uses the function "GlobalAlloc" to allocate
  918.       heap memory at the offset address 0000. Since this is a Global Heap-
  919.       operation, the Heap Debugger will not notice anything. The releasing
  920.       of this heap memory area with FreeMem will be registered. The
  921.       consequence for the Heap Debugger is the same as in the protected mode.
  922.  
  923.  
  924.       ___ BGI ________________________________________________________________
  925.  
  926.       During the initializing of BGI-Drivers the same phenomenon as described
  927.       in the section "MemAllocSeg" might occur. Mostlikely the BGI-Drivers or
  928.       the unit Graph have their own implementation of the function
  929.       "MemAllocSeg".
  930.  
  931.  
  932.       ___ TMemoryStream ______________________________________________________
  933.  
  934.       The method "ChangeListSize" of this stream-object uses MemAllocSeg,
  935.       which was described above.
  936.  
  937.       Page 17
  938.  
  939.  
  940.       ___ Heap Overrun _______________________________________________________
  941.  
  942.       The Heap Debugger, that is supposed to control the heap operations of a
  943.       program, also needs heap memory for its work. In case the heap debugger
  944.       cannot request anymore heap memory, because this is used up, then there
  945.       will be an internal error number 203 reported. When the main program
  946.       defines a heaperror-function, then this will be executed when a
  947.       heap allocation in the Heap Debugger fails.
  948.  
  949.  
  950.       ___ Program Break ______________________________________________________
  951.  
  952.       When a program, that uses the Heap Debugger, breaks execution without
  953.       the exit-procedure of the unit UseHDeb is being run, then the by the
  954.       Heap Debugger changed software interrupt vectors will not be restored.
  955.       Non restored interrupt vectors, that are not used elsewhere, are of no
  956.       danger. During a new Initialization of the Heap Debugger by a repeated
  957.       run, there will be three other interrupt vectores searched. If the
  958.       "hard" breaks repeat (approx. 40 times), there will sometime be no more
  959.       free interrupt vectores and the Heap Debugger∩s initialization will
  960.       fail. This then can only be fixed by a reboot of the computer.
  961.  
  962.  
  963.       ___ WINCRT _____________________________________________________________
  964.  
  965.       If the main program is already using a WinCrt-Window and this is not
  966.       closed with DoneWinCrt, before the exit-procedure of the Unit UseHDeb is
  967.       run, then typically 2000 bytes of heap memory stay allocated, that then
  968.       is listed in the Heap Debugger Report.
  969.  
  970.       Anyhow you should not be program a DoneWinCrt-command into the main
  971.       program, because this brings up new problems.
  972.  
  973.       As already described in the section "DLLs", the Heap Debugger cannot
  974.       dump into a WinCrt-window when a DLL is being used.
  975.  
  976.       In case of doubt you should try to take advantage of the possibility of
  977.       the dumping the report into a file.
  978.